<template>
  <div>
    <el-row type="flex" justify="center">
      <el-input v-model="numberString" size="mini"></el-input>
      <el-button type="primary" size="mini" @click="onSubmit">开始排序</el-button>
    </el-row>
    <div id="myChart" :style="{width: '600px', height: '600px'}"></div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      finishedList: [],
      stop: false,
      numberString: '7,6,5,4,8,9,10',
      myChart: undefined,
      numbers: [],
      data: [],
      xData: [],
      option: {
        xAxis: {
          type: 'category',
          data: [],
          animationDuration: 0,
          animationDurationUpdate: 400,
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          // realtimeSort: true,
          data: [{
            value: undefined,
            itemStyle: {
              color: '#6e7074'
            }
          }],
          type: 'bar',
          label: {
            show: true,
            position: 'top'
          }
        }],
        animationDuration: 0,
        animationDurationUpdate: 400
      },
      stateObjectArray: [{
        keyIndex: undefined,
        data: [],
        finishedList: []
      }]
    }
  },
  components: {},
  mounted() {
    this.initialEcharts()
  },
  watch: {},
  computed: {},
  created() {
  },
  methods: {
    onSubmit() {
      this.stop = true
      setTimeout(() => {
        this.resetData()
        this.dealWithInput()
        this.getFirstStateObject()
        this.setOption()
        this.sort()
        for (let i = 0; i < this.stateObjectArray.length; i++) {
          // console.log(this.stateObjectArray[i].keyIndex, this.stateObjectArray[i].data.map(x => x.value), this.stateObjectArray[i].finishedList)
        }
        this.stop = false
        this.draw()
      }, 1000)
    },
    swap(index1, index2) {
      let t = JSON.parse(JSON.stringify(this.data[index1].value))
      let x = JSON.parse(JSON.stringify(this.data[index2].value))
      this.data[index1].value = x;
      this.data[index2].value = t;
    },
    move(fromIndex, toIndex) {
      this.data[toIndex].value = JSON.parse(JSON.stringify(this.data[fromIndex].value));
    },
    sort() {
      for (let i = 1; i < this.data.length; i++) {
        let key = this.data[i].value
        let compareIndex = i - 1
        let keyIndex = compareIndex + 1
        this.pushStateObject(keyIndex)
        // console.log('---i= ', i, '---')
        // console.log(this.data.map(x => x.value))
        while (compareIndex >= 0 && this.data[compareIndex].value > key) {
          // console.log('compareIndex:', compareIndex)
          // this.swap(compareIndex, keyIndex)
          this.move(compareIndex, keyIndex)
          compareIndex--;
          keyIndex--;
          // console.log('compareIndex:', compareIndex)
          // console.log(this.data.map(x => x.value))
          this.pushStateObject(compareIndex + 1)
        }
        this.data[compareIndex+1].value = JSON.parse(JSON.stringify(key))
        this.finishedList.push(i)
        this.pushStateObject(compareIndex + 1)
      }
      // console.log(this.data.map(x => x.value))
    },
    setOption() {
      this.option.xAxis.data = this.xData
      this.option.series[0].data = this.data
      this.myChart.setOption(this.option)
    },
    getFirstStateObject() {
      let x = JSON.parse(JSON.stringify(this.data));
      x.finishedList = new Array()
      this.stateObjectArray[0].data = x;
    },
    pushStateObject(keyIndex) {
      let lastState = JSON.parse(JSON.stringify(this.stateObjectArray[this.stateObjectArray.length - 1]))
      lastState.keyIndex = keyIndex
      lastState.data = JSON.parse(JSON.stringify(this.data))

      lastState.finishedList = JSON.parse(JSON.stringify(this.finishedList))
      this.stateObjectArray.push(lastState)
    },
    draw() {
      let i = 0
      let outLoop = () => {
        if (i >= this.stateObjectArray.length) {
          return
        } else {
          this.drawState(this.stateObjectArray[i])
          setTimeout(() => {
            if (!this.stop) {
              i++;
              outLoop();
            }
          }, 800)
        }
      }
      outLoop()
    },
    drawState(state) {
      if (state.finishedList.length === state.data.length) {
        for (let i = 0; i < state.finishedList.length; i++) {
          state.data[state.finishedList[i]].itemStyle.color = '#333333'
        }
      } else {
        let array = state.finishedList.push(state.keyIndex)
        let re = state.data.filter(x => !this.arrayContainsNumber(array, x.value))
        for (let i = 0; i < re.length; i++) {
          re[i].itemStyle.color = '#6e7074'
        }
        if (state.finishedList && state.finishedList.length > 0) {
          for (let i = 0; i < state.finishedList.length; i++) {
            state.data[state.finishedList[i]].itemStyle.color = '#333333'
          }
        }

        let keyIndex = state.keyIndex
        state.data[keyIndex].itemStyle.color = '#FF7C7C'
      }
      this.option.series[0].data = state.data
      this.myChart.setOption(this.option)
    },
    arrayContainsNumber(array, number) {
      for (let i = 0; i < array.length; i++) {
        if (array[i] === number) {
          return true
        }
      }
      return false
    },
    resetData() {
      this.finishedList = [0]
      this.xData = []
      this.option.xAxis.data = []
      this.option.series[0].data = []
      this.data = []
      this.stateObjectArray = [{
        keyIndex: 0,
        data: [],
        finishedList: [0]
      }]
    },
    dealWithInput() {
      // 转为数字
      let numbers = this.numberString.split(',').map(x => parseInt(x)).filter(m => this.isRealNum(m))
      // 获取series[0].data数据
      this.data = numbers.map(x => {
        return {
          value: x, itemStyle: {
            color: '#6e7074'
          }
        }
      })
      // 获取x轴数值
      for (let i = 0; i < numbers.length; i++) {
        this.xData.push(i)
      }
    },
    isRealNum(value) {
      if (value === '' || value === null) {
        return false
      }
      return !isNaN(value) && typeof value === 'number'
    },
    initialEcharts() {
      var chartDom = document.getElementById('myChart');
      this.myChart = this.$echarts.init(chartDom)
    }
  }
}

</script>
<style>

</style>
